﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StyleMVVM.Utilities;
using StyleMVVM.Validation;
#if NETFX_CORE
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

#else
using System.Windows;
using System.Windows.Controls;

#endif

namespace StyleMVVM.View
{
	public sealed class Validation
	{
		public static bool GetAssignMessageToTooltip(DependencyObject obj)
		{
			return (bool)obj.GetValue(InternalAssignMessageToTooltipProperty);
		}

		public static void SetAssignMessageToTooltip(DependencyObject obj, bool value)
		{
			obj.SetValue(InternalAssignMessageToTooltipProperty, value);
		}

		public static DependencyProperty AssignMessageToTooltipProperty
		{
			get { return InternalAssignMessageToTooltipProperty; }
		}

		// Using a DependencyProperty as the backing store for AssignMessageToTooltip.  This enables animation, styling, binding, etc...
		internal static readonly DependencyProperty InternalAssignMessageToTooltipProperty =
			DependencyProperty.RegisterAttached("AssignMessageToTooltip",
			                                    typeof(bool),
			                                    typeof(Validation),
			                                    new PropertyMetadata(true));

		public static string GetMessage(DependencyObject obj)
		{
			return (string)obj.GetValue(InternalMessageProperty);
		}

		public static void SetMessage(DependencyObject obj, string value)
		{
			obj.SetValue(InternalMessageProperty, value);
		}

		public static DependencyProperty MessageProperty
		{
			get { return InternalMessageProperty; }
		}

		// Using a DependencyProperty as the backing store for Message.  This enables animation, styling, binding, etc...
		internal static readonly DependencyProperty InternalMessageProperty =
			DependencyProperty.RegisterAttached("Message", typeof(string), typeof(Validation), new PropertyMetadata(string.Empty));

		public static string GetProperty(DependencyObject obj)
		{
			return (string)obj.GetValue(InternalPropertyProperty);
		}

		public static void SetProperty(DependencyObject obj, string value)
		{
			obj.SetValue(InternalPropertyProperty, value);
		}

		// Using a DependencyProperty as the backing store for Property.  This enables animation, styling, binding, etc...
		internal static readonly DependencyProperty InternalPropertyProperty =
			DependencyProperty.RegisterAttached("Property",
			                                    typeof(string),
			                                    typeof(Validation),
			                                    new PropertyMetadata(null, PropertyChanged));

		private static void PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			FrameworkElement element = d as FrameworkElement;

			if (element != null && !DesignMode.IsEnabled)
			{
				DataContextChangedHelper.UnregisterDataContextChangeHandler(d, ProcessDataContextChanged);

				if (!string.IsNullOrEmpty(e.NewValue as string))
				{
					ProcessDataContextChanged(element, null, element.DataContext);

					DataContextChangedHelper.RegisterDataContextChangeHandler(element, ProcessDataContextChanged);
				}
			}
		}

		private static void ProcessDataContextChanged(FrameworkElement element, object oldContext, object newContext)
		{
			if (element is Control)
			{
				IValidationService validationService =
					Bootstrapper.Instance.Container.LocateByType(typeof(IValidationService)) as IValidationService;

				if (oldContext != null)
				{
					ValidationHelper helper = ValidationHelper.GetHelper(element);

					helper.Close();
				}

				if (newContext != null)
				{
					ValidationHelper newHelper = new ValidationHelper(element as Control,
					                                                  newContext,
					                                                  GetProperty(element),
					                                                  validationService);

					ValidationHelper.SetHelper(element, newHelper);
				}
			}
		}
	}
}